home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The 640 MEG Shareware Studio 2
/
The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO
/
clang
/
cuj1008.zip
/
1008090A
< prev
next >
Wrap
Text File
|
1992-02-17
|
14KB
|
411 lines
/*--------------------------------------------------*
* *
* Module: GetTouch.c *
* Purpose: To provide an intelligent interface *
* to the Elographics ELODEV TSR from an *
* application that must distinguish *
* between button and curve type touches.*
* Author: W. Harvey Gray *
* Compiler: Microsoft 5.0 *
* *
* External GetTouch *
* Functions: InitializeTouch *
* ReplayTouch *
* SetButtonRadius *
* TouchInfo *
* *
* Variables: There are no external variables used *
* or defined by this module. *
* *
* Copyright 1992, W. Harvey Gray. May be used *
* freely, if authorship and publication are *
* acknowledged. *
* *
*--------------------------------------------------*/
#include <math.h>
#include <stdio.h>
#include "dvrfunc.h"
#include "GetTouch.h"
/*--------------------------------------------------*
* module defines *
*--------------------------------------------------*/
#define TOUCH_BUF_NUM 50 /* Internal buffer size. */
/*--------------------------------------------------*
* static variables *
*--------------------------------------------------*/
static boolean is_button; /* Is a button flag */
static boolean from_tbuff; /* Touch in buffer flag */
static boolean overflow; /* Buff storage exceeded */
static int num_returned; /* Total touch points */
static int num_touch; /* Count of touch points */
static int ut; /* Touch point untouch flag */
static int xt; /* Touch point x coordinate */
static int yt; /* Touch point y coordinate */
static long radius2; /* Square of button radius */
static long dist2; /* Distance variable */
static long xcen; /* X centroid of touch */
static long xsum; /* X sum of touch points */
static long ycen; /* Y centroid of touch */
static long ysum; /* Y sum of touch points */
/*--------------------------------------------------*
* touch buffer and pointers *
*--------------------------------------------------*/
static struct touchit touch_information;
static struct touchit *pti = &touch_information;
static struct touchxy touch[TOUCH_BUF_NUM];
static struct touchxy tub;
static struct touchxy *ptouch = &touch[0];
static struct touchxy *ptub = &tub;
/*--------------------------------------------------*
* static prototypes *
*--------------------------------------------------*/
static struct touchxy *buffered( boolean * );
static struct touchxy *unbuffered( boolean * );
static void buffer_touch( void );
static void store_touch( struct touchxy * );
/*--------------------------------------------------*
* extern function GetTouch() *
*--------------------------------------------------*/
struct touchxy *GetTouch( boolean *button ) {
/*--------------------------------------------------*
* Purpose: *
* *
* Function GetTouch doesn't accept any inputs *
* from the caller and returns two values. If *
* there is a touch in progress, then GetTouch *
* returns a pointer to a struct that contains the *
* next touch point coordinate pair. If no touch *
* is in progress, then GetTouch returns a NULL *
* pointer to a touchxy struct. Also returned via *
* a pointer to the boolean button variable is the *
* logical value of the button flag. If TRUE, then *
* the touch should be interpreted like the user *
* touched a button. If FALSE, then the touch *
* should be interpreted like the user is drawing *
* a curve. *
* *
*--------------------------------------------------*/
if ( from_tbuff )
return buffered( button );
/*----------------------------------------------*
* If there is no touch, then return immedi- *
* ately pointing to a null touch point. *
*----------------------------------------------*/
if ( ! gettouch( &xt, &yt, &ut ) )
return (struct touchxy *) NULL;
/*----------------------------------------------*
* If the space in the touch buffer has been *
* exceeded, then simply return the touch point.*
*----------------------------------------------*/
if ( overflow )
return unbuffered( button );
/*----------------------------------------------*
* The last special case occurs when an *
* untouch occurs on the first touch point. If *
* this happens, simply return the untouch pt. *
*----------------------------------------------*/
else if ( ut ) {
ptub->xt = xt;
ptub->yt = yt;
ptub->ut = ut;
*button = TRUE;
return ptub;
}
/*----------------------------------------------*
* If here, then the touch point is the first *
* touch point of a new touch. Begin by buffer-*
* ing (at most) TOUCH_BUF_NUM touch points. *
*----------------------------------------------*/
is_button = TRUE; /* Assume it's a button. */
num_touch = 1; /* Init. number of touch points */
ptouch = &touch[0]; /* Init. touch buffer ptr. */
ptouch->xt = xt; /* Store touch point */
ptouch->yt = yt;
ptouch->ut = ut;
xcen = xsum = (long) xt; /* Init. touch pt cen. */
ycen = ysum = (long) yt;
buffer_touch(); /* Fill the touch buffer */
/*----------------------------------------------*
* Setup so that the touch can be extracted *
* from its internal buffer and return the *
* first touch point. *
*----------------------------------------------*/
from_tbuff = TRUE;
num_returned = 1;
ptouch = &touch[0];
*button = is_button;
return ptouch;
}
/*--------------------------------------------------*
* extern function InitializeTouch() *
*--------------------------------------------------*/
void InitializeTouch( void ) {
/*--------------------------------------------------*
* Purpose: *
* *
* Initialize the internal variables of the *
* GetTouch module. *
* *
*--------------------------------------------------*/
is_button = FALSE;
from_tbuff = FALSE;
overflow = FALSE;
num_returned = 0;
num_touch = 0;
ut = FALSE;
xt = 0;
yt = 0;
radius2 = 0;
dist2 = 0;
xcen = 0;
xsum = 0;
ycen = 0;
ysum = 0;
return;
}
/*--------------------------------------------------*
* extern function ReplayTouch() *
*--------------------------------------------------*/
void ReplayTouch( boolean set_button ) {
/*--------------------------------------------------*
* Purpose: *
* *
* Replays a touch, if there is one in the buffer.*
* *
*--------------------------------------------------*/
if ( from_tbuff ) { /* Lose, if no buffer. */
num_returned = 0;
ptouch = &touch[-1]; /* It will be ++'ed. */
is_button = set_button;
}
return;
}
/*--------------------------------------------------*
* extern function SetButtonRadius() *
*--------------------------------------------------*/
void SetButtonRadius( int radius ) {
/*--------------------------------------------------*
* Purpose: *
* *
* Sends the button radius to this module. *
* *
*--------------------------------------------------*/
radius2 = (long) radius * radius;
}
/*--------------------------------------------------*
* extern function TouchInfo() *
*--------------------------------------------------*/
struct touchit *TouchInfo( void ) {
/*--------------------------------------------------*
* Purpose: *
* *
* Returns a pointer to a struct that contains *
* touch information. *
* *
*--------------------------------------------------*/
pti->xcen = (int) ( xsum / (long) num_touch );
pti->ycen = (int) ( ysum / (long) num_touch );
pti->n = num_touch;
pti->button = is_button;
return pti;
}
/*--------------------------------------------------*
* static function buffer_touch() *
*--------------------------------------------------*/
static void buffer_touch( void ) {
/*--------------------------------------------------*
* Purpose: *
* *
* Fill up the touch buffer by reading and storing*
* touch points. Several conditions stop filing *
* the touch buffer: if there are too many touch *
* points for the buffer, stop buffering; if the *
* touch is determined to not be a button, then *
* there is no need to continue buffering; or if *
* an untouch is encountered, then quit buffering. *
* *
*--------------------------------------------------*/
while ( num_touch < TOUCH_BUF_NUM ) {
if ( gettouch( &xt, &yt, &ut ) ) {
num_touch++;
store_touch( ++ptouch );
if ( dist2 > radius2 ) {
/* If here, then not a button push. */
/* Stop buffering. */
is_button = FALSE;
break;
}
if ( ut ) {
/* Stop buffering. */
overflow = FALSE;
break;
}
}
}
return;
}
/*--------------------------------------------------*
* static function buffered() *
*--------------------------------------------------*/
static struct touchxy *buffered( boolean *button ) {
/*--------------------------------------------------*
* Purpose: *
* *
* Returns a buffered touch checking for the end *
* of the internal touch buffer. If the end of the *
* buffer is encountered, then several conditional *
* flags are set. *
* *
*--------------------------------------------------*/
num_returned++;
ptouch++;
*button = is_button;
/* Exhausted buffer? */
if ( num_returned == num_touch ||
num_returned > TOUCH_BUF_NUM ) {
from_tbuff = FALSE;
overflow = TRUE;
}
/* Untouch buffered? */
if ( ptouch->ut ) {
from_tbuff = FALSE;
overflow = FALSE;
}
return ptouch;
}
/*--------------------------------------------------*
* static function store_touch() *
*--------------------------------------------------*/
static void store_touch( struct touchxy *pt ) {
/*--------------------------------------------------*
* Purpose: *
* *
* Stores touch point into a touch point struct *
* and calculates the instantaneous average touch *
* coordinates and the distance between this touch *
* point's coordinate and the touches average coor- *
* dinate. *
* *
*--------------------------------------------------*/
pt->xt = xt;
pt->yt = yt;
pt->ut = ut;
xsum += xt;
ysum += yt;
xcen = xsum / (long) num_touch;
ycen = ysum / (long) num_touch;
dist2 = (xt - xcen) * (xt - xcen) +
(yt - ycen) * (yt - ycen);
return;
}
/*--------------------------------------------------*
* static function unbuffered() *
*--------------------------------------------------*/
static struct touchxy *unbuffered( boolean *button ) {
/*--------------------------------------------------*
* Purpose: *
* *
* Returns an unbuffered touch point. *
* Additionally, it sets the button *
* flag if it is determined that the touch's *
* distance exceeds the button's radius. *
* *
*--------------------------------------------------*/
num_touch++;
store_touch( ptub );
if ( dist2 > radius2 ) {
is_button = FALSE; /* Touch is a button. */
}
*button = is_button;
if ( ut ) /* If untouch, reset function. */
overflow = FALSE;
return ptub;
} /* End of file. */